import BaseView from "./BaseView";
import Singleton from "./Singleton";
import { Component, Node, director,EventTarget  } from 'cc';

export enum ViewZOrder {
	BaseLayer = 0,
	LowLayer = 5,
	LowMiddleLayer = 10,
	MiddleLayer = 20,
	HighLayer = 40,
	TopLayer = 80,  
}

export default class BaseApp extends Singleton {
	private _appComponent:Component =null;

	private _eventTarget = new EventTarget(); 

	private   _openViewList:Array<BaseView> = new Array<BaseView>();

	private   _pendViewList:any=[];

	get appNode(): Node {
		if(this._appComponent == null) {
			return null;
		}

		return this._appComponent.node;
	}

	get eventTarget():EventTarget{return this._eventTarget;}

	get appComponent():Component{return this._appComponent;}

	set appComponent(go: Component) {this._appComponent = go;}

	get viewList(): Array<BaseView> {return this._openViewList;}

	// view --打开的窗体  viewdata 窗体参数 --zindex层级 --isone是否唯一实例
	// excludeState -- 同zindex的窗体处理方式： 0--不处理  --1关闭同级其它所有 2--等待其它同级的关闭
	openView<T extends BaseView>(view: new (...args) => T, viewdata:any=null,zindex:number =ViewZOrder.MiddleLayer,
		isone:boolean =true,excludeState:number = 0):T { 
		if(this._appComponent==null){
			console.log("未初始化BaseApp");

			return null;
		}
 
		if(isone && this._appComponent.node.getChildByName(view.name)!=null){
			console.log("已经打开了窗口");

			return null;
		}
        
		if(excludeState ==1) {
			this.closeViewByZIndex(zindex);
		}else if(excludeState ==2&& this.getViewByZindex(zindex)!=null) {
			this._pendViewList.push({"view":view,"viewdata":viewdata,"zindex":zindex,"isone":isone});

			return null;
		}

		const v = new view(viewdata);

		v.openView(this._appComponent.node,zindex);
		this._openViewList.push(v);

		return v;
	}

	checkToOpenView(zindex:number):void{
		if(this._pendViewList.length <1){return ;}
		let view:any;

		for (let i = 0; i < this._pendViewList.length;i++) {
			view = this._pendViewList[i];
			if(view.zindex == zindex){
				this.openView(view.view,view.viewdata,view.zindex,view.isone);
				this._pendViewList.splice(i,1);
				break;
			}
		}
	}

	runScene(scenename: string):void{
		this.closeAllView();
		this._appComponent = null;
		director.loadScene(scenename);
	}

	closeViewByZIndex(zindex:number):void{
		for (let i = 0; i < this._openViewList.length;i++) {
			const v:BaseView = this._openViewList[i];
			const vindex:number = v.zIndex;

			if(v.node!==null && vindex== zindex){
				v.closeView();
				this._openViewList.splice(i,1);
				this.checkToOpenView(vindex);
			}
		}
	}

	getView<T extends BaseView>(view: {new():T}): T {
		return this.getViewByName(view.name) as T;
	}

	getViewByName(name:string):BaseView {
		for (let i = 0; i < this._openViewList.length; i++) {
			const v:BaseView = this._openViewList[i];

			if(v.node.name == name){
				return v;
			}
		}

		return null
	}

	getViewByZindex(zindex:number):BaseView {
		for (let i = 0; i < this._openViewList.length; i++) {
			const v:BaseView = this._openViewList[i];

			if(v.zIndex == zindex){
				return v;
			}
		}

		return null
	}

	closeView<T extends BaseView>(view: {new():T}):void {
		this.closeViewByName(view.name);
	}

	closeViewByName(name:string):void{
		let v:BaseView =null;

		for (let i = 0; i < this._openViewList.length; i++) {
			v = this._openViewList[i];
			if(v.node.name == name){
				const vindex:number = v.zIndex;

				v.closeView();
				this._openViewList.splice(i,1);
				this.checkToOpenView(vindex);
				v = null;
				break;
			}
		}
	}

	closeAllView():void{
		let v:BaseView =null;

		for (let i = this._openViewList.length-1; i >=0; i--) {
			v = this._openViewList[i];
			const vindex:number = v.zIndex;

			v.closeView();
			this._openViewList.splice(i,1);
			this.checkToOpenView(vindex);
			v = null;
		}
	}
}